import { Log } from "../../../../../Core/Module/Log/Log";
import { ErrorCore } from "../../../../../Core/Module/Network/ErrorCore";
import { GetTypeOf, Type } from "../../../../../Decorator/Decorator";
import { IRequest, IResponse } from "../../../Share/Module/Message/IMessage";
import { IMHandler } from "../../../Share/Module/Message/IMHandler";
import { Session } from "../../../Share/Module/Message/Session";

export abstract class AMRpcHandler<RpcRequest extends IRequest, RpcResponse extends IResponse> extends IMHandler {

    protected abstract Run(session: Session, request: RpcRequest, response: RpcResponse);

    public override Handle(session: Session, message: Object) {
        this.HandleAsync(session, message).then();
    }

    private async HandleAsync(session: Session, message: Object) {
        try {
            let request = message as RpcRequest;
            if (request == null) {
                throw new Error(`消息类型转换错误: ${GetTypeOf(message)} to {RpcRequest}`);
            }

            let rpcId = request.RpcId;
            let instanceId = session.InstanceId;
            let response = Object.create({});

            try {
                await this.Run(session, request, response);
            } catch (e) {
                Log.Error(e);
                response.Error = ErrorCore.ERR_RpcFail;
                response.Message = e.toString();
            }
            // 等回调回来,session可以已经断开了,所以需要判断session InstanceId是否一样
            if (session.InstanceId != instanceId) {
                return;
            }
            response.RpcId = rpcId; // 在这里设置rpcId是为了防止在Run中不小心修改rpcId字段
            session.Send(response);
        } catch (e) {
            throw new Error(`解释消息失败: ${GetTypeOf(message)} ${e}`);
        }
    }

    public override GetMessageType(): Type {
        return GetTypeOf(this._MessageType);
    }

    public override GetResponseType(): Type {
        return GetTypeOf(this._ResposeType);
    }

}